#include <cstring>
#include <iostream>
#include "TinyJsonReader.h"
#include "TinyJsonValue.h"
#include "TinyJsonWriter.h"

namespace tinyjson
{
    class UnitTest
    {
    private:
        UnitTest() {}
        UnitTest(const UnitTest &) {}
        //UnitTest &operator=(const UnitTest &) {}

    public:
        static UnitTest &instance();

    private:
        static size_t m_total_test_count;
        static size_t m_pass_test_count;

    public:
        void test_all();

    private:
        void test_parse_all();
        void test_parse_literal();
        void test_parse_literal_case(const char *json);
        void test_parse_number();
        void test_parse_number_case(Number expect, const char *json);
        void test_parse_string();
        void test_parse_string_case(const String &expect, const char *json);
        void test_parse_array();
        void test_parse_array_case(const char *json);
        void test_parse_object();
        void test_parse_object_case(const char *json);
        void test_parse_invalid();
        void test_parse_invalid_case(const char *json);
        void test_generate_all();
        void test_generate_case(const char *json);
        void test_generate_tinyjsonvalue_by_hand();

    private:
        template <typename ElementType>
        bool expect_eq_actual(const ElementType &expect, const ElementType &actual);
    };

    // linux下特化版本需在类外声明
    template <>
    bool UnitTest::expect_eq_actual(const TinyJsonParseRet &expect, const TinyJsonParseRet &actual);

    template <>
    bool UnitTest::expect_eq_actual(const TinyJsonType &expect, const TinyJsonType &actual);

    template <>
    bool UnitTest::expect_eq_actual(const std::string &expect, const std::string &actual);

}